<template>
    <div class="fabric-context-menu" v-show="visible" :style="style">
        <div class="item" @click="clone()">复制</div>
        <div class="item" style="color: rgb(var(--red-6));" @click="remove()">删除</div>
    </div>
</template>
<script lang="ts">
import {defineComponent, PropType} from "vue";

export default defineComponent({
    name: 'fabric-wb-context-menu',
    props: {
        instance: {
            type: Object as PropType<any>,
            required: true,
        },
    },
    data: () => ({
        top: 0,
        left: 0,
        visible: false,
        zIndex: 0,
        activeObjects: new Array<any>()
    }),
    computed: {
        style() {
            return {
                top: this.top + 'px',
                left: this.left + 'px',
                zIndex: this.zIndex
            }
        }
    },
    mounted() {
        this.instance.getEvent().setContextMenu(this.handleMouseUp);
    },
    methods: {
        handleMouseUp(event: any) {
            try {
                const canvas = this.instance.getCanvas();
                this.activeObjects = canvas.getActiveObjects();
                if (!this.activeObjects.length) return this.hideMenu();
                // @ts-ignore
                if (event.button === 3 && event.target && event.target.id !== 'workspace') {
                    // 显示菜单，设置右键菜单位置
                    // 获取菜单组件的宽高
                    const menuWidth = 196;
                    const menuHeight = 196;
                    // 当前鼠标位置
                    let pointX = event.e ? event.e.pageX : 0;
                    let pointY = event.e ? event.e.pageY : 0;

                    // 计算菜单出现的位置
                    // 如果鼠标靠近画布右侧，菜单就出现在鼠标指针左侧
                    if ((canvas.width || 196) - pointX <= menuWidth) {
                        pointX -= menuWidth;
                    }
                    // 如果鼠标靠近画布底部，菜单就出现在鼠标指针上方
                    if ((canvas.height || 196) - pointY <= menuHeight) {
                        pointY -= menuHeight;
                    }
                    this.showMenu(pointX, pointY);
                } else {
                    this.hideMenu();
                }
            } catch (error) {
                console.log(error);
            }
        },

        showMenu(x: number, y: number) {
            this.visible = true;
            this.left = x;
            this.top = y;
            this.zIndex = 100;
        },
        hideMenu() {
            this.visible = false;
            this.left = 0;
            this.top = 0;
            this.zIndex = -100;
            this.activeObjects = new Array<any>();
        },
        remove() {
            this.instance.getCanvas().getActiveObjects().forEach((obj: any) => {
                this.instance.getCanvas().remove(obj)
            });
            this.instance.getCanvas().requestRenderAll();
            this.instance.getCanvas().discardActiveObject();
            this.hideMenu();
        },
        clone() {
            this.instance.getCanvas().getActiveObjects().forEach((obj: any) => {
                obj.clone((cloned: any) => {
                    cloned.left = (cloned.left || 0) + 10;
                    cloned.top = (cloned.top || 0) + 10;
                    this.instance.getCanvas().add(cloned);
                });
            });
            this.instance.getCanvas().requestRenderAll();
            this.instance.getCanvas().discardActiveObject();
            this.hideMenu();
        }
    }
});
</script>
<style scoped lang="less">
.fabric-context-menu {
    position: absolute;
    background-color: var(--color-bg-1);
    box-shadow: 0 0 20px rgba(0, 0, 0, 0.1);
    padding: 7px 0;

    .item {
        padding: 7px 14px;
        cursor: pointer;

        &:hover {
            background-color: var(--color-neutral-2);
        }
    }
}
</style>
